---
title: Queries in Apollo Kotlin
---

Fetching data in a predictable, type-safe way is one of the core features of Apollo Kotlin. In this guide, you'll learn how to query a GraphQL endpoint and use the result in your application.

## Prerequisites

This page assumes some familiarity with building GraphQL queries. For a refresher, we recommend [reading this guide](http://graphql.org/learn/queries/) and practicing [running queries in Apollo Sandbox](https://studio.apollographql.com/sandbox/explorer?endpoint=https%3A%2F%2Fswapi-graphql.netlify.app%2F.netlify%2Ffunctions%2Findex&explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAOIIoBiAlgDZwDORwAOkkUQIY03V2Mtt2RAGa0GTVkKEoqKGgklCAvopVIlIADQgAbhzxUOAI3n0MIEEqA).

> Because Apollo Kotlin uses standard GraphQL syntax, anything query you can run in Sandbox can also be put into `.graphql` files in your project.

This page also assumes that you've already set up Apollo Kotlin for your Android/Kotlin application. For help with setup, see the [getting started guide](../).

## Defining

In Apollo Kotlin, each query you execute is represented as an instance of a generated class that implements the [`Query` interface](https://www.apollographql.com/docs/kotlin/kdoc/apollo-api/com.apollographql.apollo.api/-query/index.html?query=interface%20Query%3CD%20:%20Query.Data%3E%20:%20Operation%3CD%3E). To generate these classes, we first need to define the GraphQL operations we want to execute.

Let's say we define a GraphQL query named `HeroQuery`, like so:

```graphql title="HeroQuery.graphql"
query HeroQuery($id: String!) {
  hero(id: $id) {
    id
    name
    appearsIn
  }
}
```

Apollo Kotlin will generate a corresponding `HeroQuery` class that we can then use to [execute the query](#executing).

To generate classes, Apollo Kotlin requires your server's schema, along with all of the `.graphql` files that contain your defined operations. It uses these to generate code you can use to execute queries and access typed results.

> All `.graphql` files in your project are combined and treated as _one_ GraphQL document. This means that fragments defined in one `.graphql` file are available across _all_ `.graphql` files. However, it _also_ means that operation and fragment names must be unique (and validation errors will occur if they aren't).


## Executing

To execute the query we [just defined](#defining), we pass a `HeroQuery` instance to the `query` method of `ApolloClient`, like so:

```kotlin {2}
val apolloClient = ApolloClient.Builder().serverUrl("https://example.com/graphql").build()
val response = apolloClient.query(HeroQuery(id = "12")).execute()
```

By default, Apollo Kotlin offloads I/O work to a background thread, which means it's safe to start GraphQL operations on the main thread. The result is also dispatched to the calling thread, and you can use the response directly to update your data.

* On the Android and JVM, the I/O work is using `Dispatchers.IO` by default. You can change this dispatcher with `ApolloClient.Builder.dispatcher`.
* On [Kotlin/native](https://kotlinlang.org/docs/native-overview.html) (iOS, macOS, ...), the request offloads the cache and network I/O to background threads that resume in the main dispatch queue. For this reason,
  the `ApolloClient` APIs assume they are called from the main thread. It isn't possible to customize the dispatcher, but cache and network
  I/O are always done in background threads.

## Results

A query's results are returned as a hierarchy of immutable classes that match the structure of the query's fields. These classes _only_ include fields that are included in the query (other schema fields are omitted).

In other words, Apollo Kotlin generates classes based on the queries you write, _not_ based on the schema you query against.

For example, given the following schema:

```graphql
enum Episode { NEWHOPE, EMPIRE, JEDI }

interface Character {
  id: String!
  name: String!
  friends: [Character]
  appearsIn: [Episode]!
}
```

And the following query:

```graphql
query HeroAndFriendsNames {
  hero {
    name
    friends {
      id
      name
    }
  }
}
```

Apollo Kotlin generates a type-safe model that looks like this (details are omitted to focus on the class structure):

```kotlin
class HeroAndFriendsNamesQuery {
  data class Data(val hero: Hero)
  data class Hero(val name: String, friends: List<Friend>)
  data class Friend(val id: String, val name: String)
}
```

Because the `HeroAndFriendsNames` query doesn't fetch `appearsIn`, this property is not part of the returned result type and cannot be accessed here. Similarly, `id` is only accessible in `Friend`, _not_ in `Hero`.

Because GraphQL supports nullability, you have compiled-time type safety. If the request is successful, all queried data (and only this data) will be accessible. There is no need to handle null fields in UI code.

## Canceling

Operation cancellation is handled via the `CoroutineScope`. Canceling the current scope cancels any associated ongoing operation.
